from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from database import get_db, get_redis
from models import WeChatQR, User
from schemas import ResponseModel, WeChatQRResponse, WeChatScanStatusResponse
import uuid
import qrcode
import io
import base64
from datetime import datetime, timedelta
from auth import create_access_token
from config import settings

router = APIRouter(prefix="/api/wechat", tags=["微信登录"])

def generate_qr_code(data: str) -> str:
    """
    生成二维码图片的base64编码
    
    Args:
        data: 要编码的数据
    
    Returns:
        str: base64编码的二维码图片
    """
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
    )
    qr.add_data(data)
    qr.make(fit=True)
    
    # 创建二维码图片
    img = qr.make_image(fill_color="black", back_color="white")
    
    # 转换为base64
    buffer = io.BytesIO()
    img.save(buffer, format='PNG')
    img_str = base64.b64encode(buffer.getvalue()).decode()
    
    return f"data:image/png;base64,{img_str}"

@router.post("/qr-generate", response_model=ResponseModel)
async def generate_wechat_qr(db: Session = Depends(get_db)):
    """
    生成微信登录二维码
    
    Args:
        db: 数据库会话
    
    Returns:
        ResponseModel: 包含二维码信息的响应
    """
    # 生成唯一的二维码ID
    qr_id = f"qr_{uuid.uuid4().hex[:12]}"
    
    # 生成二维码内容（实际应用中应该是微信登录URL）
    qr_content = f"https://open.weixin.qq.com/connect/qrconnect?appid={settings.wechat_app_id}&redirect_uri=callback&response_type=code&scope=snsapi_login&state={qr_id}"
    
    # 生成二维码图片
    qr_code_base64 = generate_qr_code(qr_content)
    
    # 保存到数据库
    db_qr = WeChatQR(
        qr_id=qr_id,
        qr_code=qr_code_base64,
        status="waiting",
        expire_time=120
    )
    
    db.add(db_qr)
    db.commit()
    db.refresh(db_qr)
    
    # 如果有Redis，也可以存储到Redis中设置过期时间
    redis_client = get_redis()
    if redis_client:
        redis_client.setex(f"wechat_qr:{qr_id}", 120, "waiting")
    
    return ResponseModel(
        code=200,
        message="二维码生成成功",
        data={
            "qrCode": qr_code_base64,
            "qrId": qr_id,
            "expireTime": 120
        }
    )

@router.get("/scan-status/{qr_id}", response_model=ResponseModel)
async def check_scan_status(qr_id: str, db: Session = Depends(get_db)):
    """
    检查微信扫码状态
    
    Args:
        qr_id: 二维码ID
        db: 数据库会话
    
    Returns:
        ResponseModel: 包含扫码状态的响应
    
    Raises:
        HTTPException: 如果二维码不存在或已过期
    """
    # 查询二维码记录
    qr_record = db.query(WeChatQR).filter(WeChatQR.qr_id == qr_id).first()
    
    if not qr_record:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="二维码不存在"
        )
    
    # 检查是否过期
    expire_time = qr_record.created_at + timedelta(seconds=qr_record.expire_time)
    if datetime.utcnow() > expire_time:
        # 更新状态为过期
        qr_record.status = "expired"
        db.commit()
        
        return ResponseModel(
            code=200,
            message="success",
            data={
                "status": "expired"
            }
        )
    
    # 构建响应数据
    response_data = {
        "status": qr_record.status
    }
    
    # 如果扫码成功，返回用户信息和token
    if qr_record.status == "success" and qr_record.user_id:
        user = db.query(User).filter(User.id == qr_record.user_id).first()
        if user:
            # 生成访问令牌
            access_token = create_access_token(data={"sub": user.username})
            
            response_data["user"] = {
                "id": user.id,
                "nickname": user.nickname,
                "avatar": user.avatar,
                "openid": user.wechat_openid,
                "token": access_token
            }
    
    return ResponseModel(
        code=200,
        message="success",
        data=response_data
    )

@router.post("/callback", response_model=ResponseModel)
async def wechat_callback(code: str, state: str, db: Session = Depends(get_db)):
    """
    微信登录回调接口
    
    Args:
        code: 微信授权码
        state: 状态参数（二维码ID）
        db: 数据库会话
    
    Returns:
        ResponseModel: 处理结果
    
    Note:
        这是一个模拟的回调接口，实际应用中需要:
        1. 使用code向微信服务器获取access_token
        2. 使用access_token获取用户信息
        3. 创建或更新用户记录
        4. 更新二维码状态
    """
    # 查询二维码记录
    qr_record = db.query(WeChatQR).filter(WeChatQR.qr_id == state).first()
    
    if not qr_record:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="无效的状态参数"
        )
    
    # TODO: 实际应用中的微信API调用逻辑
    # 1. 使用code获取access_token
    # access_token_url = f"https://api.weixin.qq.com/sns/oauth2/access_token?appid={settings.wechat_app_id}&secret={settings.wechat_app_secret}&code={code}&grant_type=authorization_code"
    # 
    # 2. 使用access_token获取用户信息
    # user_info_url = f"https://api.weixin.qq.com/sns/userinfo?access_token={access_token}&openid={openid}"
    
    # 模拟微信用户信息
    mock_wechat_user = {
        "openid": f"wx_openid_{uuid.uuid4().hex[:8]}",
        "nickname": "微信用户",
        "headimgurl": "/img/thumb.jpg"
    }
    
    # 查找或创建用户
    user = db.query(User).filter(User.wechat_openid == mock_wechat_user["openid"]).first()
    
    if not user:
        # 创建新用户
        user = User(
            username=f"wx_user_{uuid.uuid4().hex[:8]}",
            email=f"wx_user_{uuid.uuid4().hex[:8]}@wechat.com",
            hashed_password="",  # 微信用户不需要密码
            nickname=mock_wechat_user["nickname"],
            avatar=mock_wechat_user["headimgurl"],
            wechat_openid=mock_wechat_user["openid"],
            is_verified=True
        )
        db.add(user)
        db.commit()
        db.refresh(user)
    
    # 更新二维码状态
    qr_record.status = "success"
    qr_record.user_id = user.id
    db.commit()
    
    return ResponseModel(
        code=200,
        message="微信登录成功",
        data={
            "user_id": user.id,
            "qr_id": state
        }
    )

@router.post("/simulate-scan/{qr_id}", response_model=ResponseModel)
async def simulate_wechat_scan(qr_id: str, db: Session = Depends(get_db)):
    """
    模拟微信扫码（仅用于开发测试）
    
    Args:
        qr_id: 二维码ID
        db: 数据库会话
    
    Returns:
        ResponseModel: 处理结果
    """
    # 查询二维码记录
    qr_record = db.query(WeChatQR).filter(WeChatQR.qr_id == qr_id).first()
    
    if not qr_record:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="二维码不存在"
        )
    
    if qr_record.status != "waiting":
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="二维码状态无效"
        )
    
    # 模拟扫码成功，创建测试用户
    mock_openid = f"test_openid_{uuid.uuid4().hex[:8]}"
    
    # 查找或创建测试用户
    user = db.query(User).filter(User.wechat_openid == mock_openid).first()
    
    if not user:
        user = User(
            username=f"test_user_{uuid.uuid4().hex[:6]}",
            email=f"test_{uuid.uuid4().hex[:6]}@test.com",
            hashed_password="",
            nickname="测试微信用户",
            avatar="/img/thumb.jpg",
            wechat_openid=mock_openid,
            is_verified=True
        )
        db.add(user)
        db.commit()
        db.refresh(user)
    
    # 更新二维码状态
    qr_record.status = "success"
    qr_record.user_id = user.id
    db.commit()
    
    return ResponseModel(
        code=200,
        message="模拟扫码成功",
        data={
            "user_id": user.id,
            "qr_id": qr_id,
            "openid": mock_openid
        }
    )